package group.raber.dataform.handler.impl;

import group.raber.dataform.model.DataForm;
import group.raber.dataform.model.DataFormElement;
import group.raber.dataform.model.DataFormFilter;
import group.raber.dataform.model.DataFormParser;
import group.raber.dataform.model.types.ElementFilterComparePattern;
import group.raber.saber.jdbc.NameConverter;
import group.raber.saber.jdbc.query.PaginationQuery;
import group.raber.saber.jdbc.query.PaginationQueryResult;
import group.raber.saber.jdbc.query.executor.PaginationQueryExecutor;
import group.raber.saber.kit.MapKit;
import group.raber.saber.kit.StringKit;
import group.raber.saber.lang.DataBox;
import group.raber.saber.lang.ValueObject;

import java.util.IllegalFormatException;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * Created by tisir<yangsong158@qq.com> on 2017-05-29
 */
public class FunctionInHandler {

    /**
     * 列表查询的快速工具类,主要是把重复代码抽出来,无实际架构意义
     * @param <T>
     */
    public static class ListQuery<T> {
        private PaginationQueryExecutor queryExecutor;
        private DataForm dataForm;
        private Map<String, Object> queryParameters;
        private Map<String, ValueObject> filterParameters;
        private Map<String, String> sortParameters;
        private int pageSize = 15;
        private int pageIndex = 0;

        public ListQuery(PaginationQueryExecutor queryExecutor, DataForm dataForm) {
            this.queryExecutor = queryExecutor;
            this.dataForm = dataForm;
        }

        public PaginationQueryExecutor getQueryExecutor() {
            return queryExecutor;
        }

        public void setQueryExecutor(PaginationQueryExecutor queryExecutor) {
            this.queryExecutor = queryExecutor;
        }

        public DataForm getDataForm() {
            return dataForm;
        }

        public void setDataForm(DataForm dataForm) {
            this.dataForm = dataForm;
        }

        public Map<String, Object> getQueryParameters() {
            return queryParameters;
        }

        public void setQueryParameters(Map<String, Object> queryParameters) {
            this.queryParameters = queryParameters;
        }

        public Map<String, ValueObject> getFilterParameters() {
            return filterParameters;
        }

        public void setFilterParameters(Map<String, ValueObject> filterParameters) {
            this.filterParameters = filterParameters;
        }

        public Map<String, String> getSortParameters() {
            return sortParameters;
        }

        public void setSortParameters(Map<String, String> sortParameters) {
            this.sortParameters = sortParameters;
        }

        public int getPageSize() {
            return pageSize;
        }

        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }

        public int getPageIndex() {
            return pageIndex;
        }

        public void setPageIndex(int pageIndex) {
            this.pageIndex = pageIndex;
        }

        public PaginationQueryResult<T> queryPaginationList(Class<T> classType) {
            DataFormParser dataFormParse = new DataFormParser(dataForm);
            dataFormParse.parse();

            PaginationQuery query = new PaginationQuery();
            query.setIndex(pageIndex);
            query.setSize(pageSize);
            query.setQuery(dataFormParse.getQuerySql());
            query.setParameterMap(queryParameters);
//            query.setFilterMap(this.filterParameters);
            query.setSummarizesExpressions(dataFormParse.getSummaryExpression());
            //小计,合计字段
            if (query.getSummarizesExpressions() != null && query.getSummarizesExpressions().size() > 0) {
                query.setSummary(true);
                query.setWholeSummary(true);
            }

            //处理筛选器上的查询条件
            Map<String,Object> queryParameterMap = MapKit.newHashMap();
            queryParameterMap.putAll(queryParameters);
            Iterator<String> iterator = filterParameters.keySet().iterator();
            StringBuffer filterClause = new StringBuffer();
            while (iterator.hasNext()){
                String name = iterator.next();
                DataFormFilter filterItem = dataForm.getFilter(name);
                if(filterItem==null)continue;   ///过滤器不存在
                if(!filterItem.getAvailable())continue;//过滤器不可用
                if(StringKit.isBlank(filterItem.getBindFor()))continue;  //过滤器没有绑定要素字段
                DataFormElement element = dataForm.getElement(filterItem.getBindFor());
                if(element==null||!element.getAvailable())continue;//字段不可用则不能过滤
                ValueObject valueObject = filterParameters.get(name);
                if(valueObject.isNull())continue;//有过滤器,但是值为空,也忽略

                if(filterClause.length()>0)filterClause.append(" AND ");
                filterClause.append(element.getColumn());
                String fieldAlias = "_S_F_"+name;
                switch (filterItem.getComparePattern()){
                    case StartWith:
                        filterClause.append(" like ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,valueObject.strValue()+"%");
                        break;
                    case EndWith:
                        filterClause.append(" like ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,"%"+valueObject.strValue());
                        break;
                    case Contain:
                        filterClause.append(" like ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,"%"+valueObject.strValue()+"%");
                        break;
                    case Equal:
                        //等于,可以存在多个值的情况
                        if(valueObject.isArray()){
                            filterClause.append(" in (");
                            for(int i=1;i<=valueObject.objectArray().length;i++){
                                filterClause.append(":").append(fieldAlias+"_"+i);
                                queryParameterMap.put(fieldAlias+"_"+i,valueObject.objectArray()[i-1]);
                            }
                            filterClause.append(" )");
                        }else{
                            filterClause.append(" = ").append(":").append(fieldAlias);
                            queryParameterMap.put(fieldAlias,valueObject.value());
                        }
                        break;
                    case NotEqual:
                        filterClause.append(" <> ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,valueObject.value());
                        break;
                    case Range:
                        //如果是范围查询,但是值少于两个的情况下
                        if(!valueObject.isArray()||valueObject.objectArray().length<2){
                            throw new RuntimeException("the range query value requires at least two,dataform="+dataForm.getFullName()+",filterId="+filterItem.getCode());
                        }
                        filterClause.append(" BETWEEN ").append(":").append(fieldAlias).append("_1").append(" AND ").append(":").append(fieldAlias).append("_2");
                        queryParameterMap.put(fieldAlias+"_1",valueObject.objectArray()[0]);
                        queryParameterMap.put(fieldAlias+"_2",valueObject.objectArray()[1]);
                        break;
                    case GreaterThan:
                        filterClause.append(" > ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,valueObject.value());
                        break;
                    case LessThan:
                        filterClause.append(" < ").append(":").append(fieldAlias);
                        queryParameterMap.put(fieldAlias,valueObject.value());
                        break;
                    default :
                        continue;
                }

            }

            //处理筛选器和排序部分
            StringBuffer sortClause = new StringBuffer();
            Iterator<String> sortIterator = sortParameters.keySet().iterator();
            while(sortIterator.hasNext()){
                String name = sortIterator.next();
                String value = sortParameters.get(name);
                if(StringKit.isBlank(value))continue;
                value = value.replaceAll("\\s+","");
                if(sortClause.length()>0)sortClause.append(",");
                if("asc".equalsIgnoreCase(value)||"desc".equalsIgnoreCase(value)){
                    DataFormElement element = dataForm.getElement(name);
                    if(element==null||!element.getAvailable())continue;//字段不可用则不能过滤
                    sortClause.append(" ").append(element.getColumn()).append(" ").append(value);
                }else{
                    throw new RuntimeException("the sort value must be ASC or DESC,sort:["+value+"]");
                }
            }

            query.setParameterMap(queryParameterMap);
            if(filterClause.length()>0){
                query.setQuery(query.getQuery()+" AND ("+filterClause.toString()+")");
            }
            if(sortClause.length()>0){
                query.setQuery(query.getQuery()+" order by  "+sortClause.toString()+"");
            }
            PaginationQueryResult<T> result = queryExecutor.query(query, classType, dataFormParse.getFieldsMap(), dataFormParse.getSummaryFieldsMap());
            return result;
        }

    }
}
